﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.ComponentModel;

namespace CIS.Web.Binders
{
	interface IPropertyBinder
	{
		object BindModel(ControllerContext controllerContext,
					ModelBindingContext bindingContext,
					MemberDescriptor memberDescriptor);
	}

	public class PropertyBinderAttribute : Attribute
	{
		public PropertyBinderAttribute(Type binderType)
		{
			BinderType = binderType;
		}

		public Type BinderType { get; private set; }
	}


	public class CustomeModelBinder : DefaultModelBinder
	{
		protected override void BindProperty(ControllerContext controllerContext,
					ModelBindingContext bindingContext,
					PropertyDescriptor propertyDescriptor)
		{
			var propertyBinderAttribute = TryFindPropertyBinderAttribute(propertyDescriptor);
			if (propertyBinderAttribute != null)
			{
				var binder = CreateBinder(propertyBinderAttribute);
				var value = binder.BindModel(controllerContext, bindingContext, propertyDescriptor);
				propertyDescriptor.SetValue(bindingContext.Model, value);
			}
			else // revert to the default behavior.
			{
				base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
			}
		}

		IPropertyBinder CreateBinder(PropertyBinderAttribute propertyBinderAttribute)
		{
			return (IPropertyBinder)DependencyResolver.Current.GetService(
						    propertyBinderAttribute.BinderType);
		}

		PropertyBinderAttribute TryFindPropertyBinderAttribute(PropertyDescriptor propertyDescriptor)
		{
			return propertyDescriptor.Attributes
				  .OfType<PropertyBinderAttribute>()
				  .FirstOrDefault();
		}
	}
}